(function(){
    function updateServiceTabs(icon, elem, expand){
        var inner = elem.find('.list-inner');
        var tab = elem.find('li.active a');

        if (tab.length && !tab.data('tab'))
            tab.tab().trigger('show');

        if (!inner.is(':visible') || expand === true){
            icon.removeClass('plus').addClass('minus');
            inner.show();
        } else {
            icon.removeClass('minus').addClass('plus');
            inner.hide();
        }
    }

    // delegated event update icon and show/hide tab elements
    // TODO generalize this
    $(document).on('click', '.content-list h3, h3.expand-all', function(ev){
        var icon = $(this);

        if (icon.hasClass('expand-all')){
            var parent = icon.closest('div');
            var elems = parent.children('ul').children();

            for (var i = 0; i < elems.length; i++){
                var service = elems.eq(i);
                var icon = service.find('i.plus');

                updateServiceTabs(icon, service, true);
            }

        } else {
            icon = icon.find('i');

            var parent = icon.closest('li');
            updateServiceTabs(icon, parent);
        }
    }).on('click', '.content-list i', function(ev){
        ////$(this).parent().trigger('click');
    });
}());

// bootstrap tab#show event
$(document).on('show', 'a[data-toggle="tab"]', function(ev){
    var elem = $(ev.target);
    var tab = elem.data('tab');

    if (tab.original_show)
        return;

    // we need to dynamically patch bootstrap's tab plugin
    tab.original_show = tab.show;
    tab.show = function(){
        var parent = elem.parent();

        if (parent.hasClass('active') && elem.data('closable') !== false){
            // if were clicking on the active one close it
            var tabs = parent.parent();
            var panes = tabs.next();

            // tabs and panes aren't right next to each other in the DOM
            // go up one more parent and use the next element
            if (!panes.length)
                panes = tabs.parent().next();

            // active an empty tab
            var empty = $([]);

            this.activate(empty, tabs);
            this.activate(empty, panes);

        } else {
            // otherwise just call the original show code
            this.original_show();
        }
    };
});

jpackage("twc.account.equipment.models", function() {
	var template = twc.utils.template;
	var collections = twc.account.equipment.collections;
	var cookie_domain;// = ".timewarnercable.com";

	this.Device = Backbone.Model.extend({
		defaults: {
			status: '',
			message: '',
			macAddress: '',
			lob: '',
			attempts: 0,
			isOutageOccurring: false,
			serialNumber: '',
			isCritical: false,
			isLowMemory: false,
			// TODO: Saving attemptedTroubleshoot as an object or array is not working.
			//		 The reason it fails is not obvious and is taking too much time to debug.
			// 		 Saving as a string fixes the problem, but requires the value to be
			//       converted between string and json when reading and writing, which is
			//		 not ideal. This needs to be debugged at some point. -JH
			attemptedTroubleshoot: "",
			isDumbDevice: false,
            make: '',
            type: ''
		},

		url: function() {
			return twc.routes.get('account/equipment-health');
		},

		maxAttempts: 4,

		messages: {
			LOADING: 'Verifying Status <small>This may take up to 30 seconds</small>',
			GOOD: 'Connected',
			NOT_GOOD: 'Not Connected',
			NOT_FOUND: 'Not Connected',
			UNAVAILABLE: 'Status Unknown',
			OUTAGE: 'Outage'
		},

		initialize: function( options ) {
			var cookie = twc.utils.StorageUtil.read (this.getKeyName(), true);

			for( var i in cookie ) {
				//to prevent serialNumber from getting overwritten by bad values
				//from failed fetch
				if (i != 'serialNumber' || (cookie[i] && cookie[i] != "null")) {
					this.set( i, cookie[i] );
				}
			}

			this.url = options.url || this.url;
			this.on('change:status', this.onChangeStatus, this);
		},

		isLoading: function() {
			return this.get('status') == 'LOADING'
		},
		
		canTroubleshoot: function() {
			return this.get('status') != 'NOT_FOUND'
		},

		saveCookie: function() {
			twc.utils.StorageUtil.write(this.getKeyName(), this.attributes) ;
		},

		clearCount: function() {
			this.set('attempts', 0);
			this.saveCookie();
		},

		clearCookie: function() {
			twc.utils.StorageUtil.erase( this.getKeyName() );
		},

		hasCookie: function() {
			return twc.utils.StorageUtil.read(this.getKeyName()) != "";
		},

		fetch: function( options ) {
			if (this.get('isDumbDevice')) return false;
			var params =  _.extend({ mac: this.get('macAddress'), make: this.get('make'),  deviceType: this.get('type')}, options );
			var self = this, xhr;
			var attempts = this.get('attempts');
			//save serialNumber in case it gets overridden later
			var serialNumber = this.get('serialNumber');
	
			if( this.get('attempts') >= this.maxAttempts )
				return false;
	
			this.set('attempts', this.get('attempts') + 1);
			this.set('status', 'LOADING');
	
			xhr = Backbone.Model.prototype.fetch.call( this, { data: params });
	
			xhr.fail(function(){
				self.set('status', 'UNAVAILABLE');
			}).always(function(){
				//if the device has issues, it might return a null serial number
				//this if is here to prevent our serial number from getting overridden
				if (!self.get('serialNumber') || self.get('serialNumber') == "null") {
					self.set('serialNumber', serialNumber);
				}
				self.saveCookie();
	
				if (!self.collection || !self.collection.isLoading()){
					self.trigger('complete', self);
				}
			});
	
			return xhr;
		},

		onChangeStatus: function( model, value ) {
			this.set({ message: this.messages[value] || this.messages["UNAVAILABLE"] });
		},

		getKeyName: function() {
			return 'mys-device' + this.get('macAddress') + this.get('lob');
		}
	});

});

jpackage("twc.account.equipment.collections", function() {
	this.Devices = Backbone.Collection.extend({
		model: twc.account.equipment.models.Device,
		loading: false,
		loadCount: 0,
		lobs: [],
		lobOutage : {
			'tv' : false,
			'homephone' : false,
			'internet' : false
		},
		clearCounts: function() {
			this.each(function(value, key, list) {
				value.clearCount();
			})
		},

		clearCookies: function() {
			this.each(function(value, key, list) {
				value.clearCookie();
			})
		},
		hasCookies : function() {
			var hasCookies = true;
			this.each(function(value, key, list) {
				//Disregard dumb devices when checking status. They will never have a status.
				hasCookies &= value.hasCookie() && value.get('isDumbDevice') || value.get('status') != "";
			});
			return hasCookies;
		},
		fetch: function() {
			var collection = this;
			var promises   = [];

			this.each(function( value, key, list ){
				var xhr, dfd;

				if (xhr = value.fetch()){
					// we need to wrap the actual XHR Deferred in a
					// new dfd so we can properly handle failures
					dfd = $.Deferred();
					xhr.always(dfd.resolve);

					promises.push(dfd);
				}
			});
			
			this.promise = $.when.apply($, promises).always(function(){
				collection.onFetchComplete();
			});

			// at least one model#fetch() returned a jqxhr promise
			return !!promises.length;
		},
		hasProvisionalDevices: function() {
			var provisionalDevice = false;
			this.each(function( value, key, list ){
				if (!value.get('isDumbDevice')) {
					provisionalDevice = true;
				}
			});
			return provisionalDevice;
		},
		isOutageOccurring: function() {
			return this.find(function( model ) {
				return model.get('isOutageOccurring');
			})
		},
		isOutageOccurringForLob: function(lob) {
			return this.find(function( model ) {
				return model.get('isOutageOccurring') && model.get('lob') == lob;
			})
		},
		isPotentialOutage: function() {
			var hasLobs = this.lobs.length > 1;
			var hasStatus = this.find(function( model ) {
				return model.get('status') !== 'NOT_FOUND';
			});

			return hasLobs && hasStatus === undefined;
		},

		onFetchComplete: function() {
			this.trigger('complete');
		},


		isLoading:function(){
			return this.promise && this.promise.state() == 'pending';
		}
	});

});

jpackage("twc.account.equipment.views", function() {
	var omni = { GOOD: 'ol', NOT_GOOD: 'if', NOT_FOUND: 'na', UNAVAILABLE: 'su' };

	var views = this;
	var models = twc.account.equipment.models;
	var collections = twc.account.equipment.collections;

	function trackStatus( devices, el ){
		if (!_.isArray(devices)) devices = [devices];
		if (devices.length == 0) { return; }

		var hasOutage = _.any(devices, function(d){ return d.outage; });
		var list = _.map(devices, function(d){ return omni[d.status] +':'+ d.name; });
		
		var id = el.find('.tab-pane.active').attr('id');
		var section = (id || '').split('-')[1] || '';

		var props = {
			events: 'event48',
			e7: _.flatten(['ehc', devices.length > 1 ? [] : [section, devices[0].name], 'check status']).join(':'),
			p57: list.join(',')
		};

		if (hasOutage){
			props.p63 = props.e63 = 'ehc:'+ section +':outage message';
			props.events += ',event92';
		}
		
		twc.omniture.track('event', 'ehc:status', props);
	}

	this.DeviceDisplay = Backbone.View.extend({
		events: {
			'click .check-connection' : 'onCheckClick',
			'click .troubleshoot-connection' : 'onTroubleshootClick',
			'click .refresh-connection' : 'onRefreshClick'
		},

		initialize: function( options ) {
			this.troubleshoot = options.troubleshoot;
			this.parent = options.parent;

			this.checkConnection = $('.check-connection', this.$el);
			this.equipmentStatus = $('.equipment-status', this.$el );
			this.statusMessage = $('.status-message', this.equipmentStatus );
			this.refresh = $('.refresh-connection', this.equipmentStatus );

			this.model.on('change:status', this.onFirstChange, this);
			this.model.on('change:status', this.onStatusChange, this);

			//set whether it is a non-provisionable (dumb) device
			this.model.set("isDumbDevice", $(this.$el).hasClass("dumb-device"));
			
			if( this.model.get('status') != '' ) {
				this.onFirstChange();
				this.updateStatus( this.model, this.model.get('status'), '');
			}
		},

		updateStatus: function( model, newValue, oldValue ) {
			var newClass = newValue.split('_').join('-').toLowerCase();
			var oldClass = oldValue.split('_').join('-').toLowerCase();
			var isOutage = this.parent.outageFeatureEnabled && ((model.get('isOutageOccurring') || this.parent.getOutageForLob(model.get('lob')))
					&& !model.isLoading());

			var outageClass = 'outage';
			var outageMessage = model.messages.OUTAGE;
			var statusClass = isOutage ? outageClass : newClass;
			var statusMessage = isOutage ? outageMessage : model.get('message');

			this.equipmentStatus.removeClass( oldClass );
			this.equipmentStatus.addClass( statusClass );
			this.statusMessage.html( statusMessage );
			this.refresh.attr( 'disabled', newClass == 'loading' );
		},

		onCheckClick: function() {
			this.onRefreshClick();
		},
		
		onTroubleshootClick: function() {
			if (this.troubleshoot) 
				this.parent.troubleshootDevice(this);
		},

		onRefreshClick: function() {
			if( !this.model.fetch() ) {
				twc.errors.view.render(twc.copy.get('account/max-attempts-title'), twc.copy.get('account/max-attempts-body') );
			}
		},

		onFirstChange: function() {
			if (!this.troubleshoot)
				this.checkConnection.hide();

			this.equipmentStatus.css({ height: 'auto' });
			this.model.off('change:status', this.onFirstChange, this);
		},

		onStatusChange: function( model, newValue ) {
			var oldValue = model.previous('status');
			this.updateStatus( model, newValue, oldValue );
		},

		getTrackingValues:function(){
			return {
				status: this.model.get('status'),
				outage: this.model.get('isOutageOccurring'),
				name: this.getFullDeviceName()
			};
		},

		getFullDeviceName:function(){
			return this.equipmentStatus.parent().find('.details .device-name').map(function(){
				return $.trim(this.innerHTML.toLowerCase().replace(/:/g, ''));
			}).toArray().join(' ');
		},
		
		showDevice: function() {
			this.$el.show();
		}
	});
	this.ServicesContent = Backbone.View.extend({
		el: '#service-tab-content',
		events : {
			'click .need-help' : "needHelpClicked"
		},
		initialize : function(options) {
			this.parent = options.parent;
		},
		needHelpClicked : function(e) {
			var lob = $(e.target).data('lob');
			this.parent.startTroubleshooting(lob);
		}
	});

	this.Troubleshoot = Backbone.View.extend({
		troubleshootContainerTemplate : 'troubleshoot-container-template',
		troubleshootUnavailableTemplate: 'troubleshoot-unavailable-template',
		troubleshootSymptomTemplate : 'troubleshoot-symptom-template',
		troubleshootCriticalStatusTemplate: 'troubleshoot-critical-status-template',
		troubleshootLowMemoryTemplate : 'troubleshoot-low-memory-template',
		troubleshootRebootTemplate : 'troubleshoot-reboot-template',
		troubleshootInProgressTemplate : 'troubleshoot-in-progress-template',
		troubleshootLowMemoryInProgressTemplate : 'troubleshoot-low-memory-in-progress-template',
		troubleshootErrorTemplate : 'troubleshoot-error-template',
		troubleshootManualTemplate : 'troubleshoot-manual-template',
		troubleshootAttemptedTemplate : 'troubleshoot-attempted-template',
		lobTabs : '#equipment-lob-tabs li a',
		lobSelect : '.equipment-service-select',
		troubleshootLoading : '.troubleshoot-loading',
		accountEquipment : '#account-equipment-tab',
		outageAlert : '#troubleshoot-outage',
		potentialOutageAlert : '#troubleshoot-potential-outage',
		servicesInstructions : '#services-instructions',
		troubleshootInstructions : '#troubleshoot-instructions',
		troubleshootTab: '#troubleshoot-tab',
		equipmentTab: '#equipment-tab',
		servicesTab: '#services-tab',
		currentDevice: null,
		quicklink: 'a.troubleshoot-quicklink',
		noEquipment : 'div#troubleshoot-no-equipment',
		hasEquipment : 'div#has-equipment-container',
		events: {
			'click #troubleshoot-tab' : 'troubleshootTabClicked',
			'click .troubleshoot-all': 'startTroubleshooting',
			'click #equipment-tab' : 'equipmentTabClicked',
			'click #services-tab' : 'servicesTabClicked',
			'click #troubleshoot-change-equipment-tv' : 'untroubleshootDevice',
			'click #troubleshoot-change-equipment-internet-homephone' : 'untroubleshootDevice',
			'change .equipment-service-select' : 'lobChanged',
			'click .automated-troubleshoot .troubleshoot-symptom' : 'showTroubleshootReboot',
			'click .automated-troubleshoot .view-symptoms' : 'showTroubleshootSymptoms',
			'click .automated-troubleshoot .request-hit' : 'requestHit',
			'click .automated-troubleshoot .expand-troubleshoot' : 'expandTroubleshootingTips',
			'click #troubleshoot-no-equipment .expand-tv-troubleshoot' : 'expandTVTroubleshootingTips',
			'click .troubleshoot-chat-link' : 'trackTroubleshootChat',
			'click .equipment-bottom-tabs .troubleshooting-tips a' : 'trackTroubleshootTips',
			'click #account-equipment-tab .contact-us' : 'trackTroubleshootContactUs'
		},
		completedFetch : function() {
			this.$el.removeClass('fetching-troubleshoot');
			this.checkForSingularDevice();
		},
		troubleshootTabSelected : function() {
			return this.$troubleshootTab.parent('li').hasClass('active');
		},
		initialize : function(options) {
			var self = this;
			this.parent = options.parent;

			this.$accountEquipment = $(this.accountEquipment);
			this.$troubleshootLoading= $(this.troubleshootLoading);
			this.$outageAlert = $(this.outageAlert);
			this.$potentialOutageAlert = $(this.potentialOutageAlert);
			this.$troubleshootTab= $(this.troubleshootTab);
			this.$equipmentTab= $(this.equipmentTab);
			this.$servicesTab= $(this.servicesTab);
			this.$noEquipment = $(this.noEquipment);
			this.$hasEquipment = $(this.hasEquipment);
			this.$servicesInstructions= $(this.servicesInstructions);
			this.$troubleshootInstructions= $(this.troubleshootInstructions);

			$(this.quicklink).click(_.bind(this.quicklinkClicked, this));

			this.setDefaultEquipmentTab();
			//remove the troubleshooting tips data-omni attribute. 
			//tracking is done differently when troubleshooting is enabled
			$('.equipment-bottom-tabs .troubleshooting-tips a').removeAttr('data-omni');

			this.servicesContentView = new views.ServicesContent({parent: self})
		},
		setDefaultEquipmentTab : function() {
			//show appropriate tab
			if ($('.equipment-service-select option').length) {
				var tabClass = $('.equipment-service-select').val();
				$(this.lobTabs + "." + tabClass).tab('show');
				$(this.lobSelect).val(tabClass);
			} else if ($('.equipment-service-select span').length) {
                var tabClass = $(this.lobSelect+' span').data('lobValue');
                $(this.lobTabs + "." + tabClass).tab('show');
            }
		},
		checkLobForSize : function(lob) {
			var size = this.parent.getEquipmentSize();
			var lobSize = size;

			if (typeof(lob) == "string") {
				lobSize = this.parent.getLobEquipmentSize(lob);
			} else {
				lob = $(".products-container .product-content .need-help").data("lob");
			}

			if (!size || !lobSize) {
				this.$noEquipment.removeClass();
				this.$noEquipment.addClass(lob);

				this.$noEquipment.show();
				this.$hasEquipment.hide();
				return true;
			} else {
				this.$noEquipment.hide();
				this.$hasEquipment.show();
				//set lob
				return false;
			}
		},
		checkForSingularDevice : function() {
			var lobSpan = $('.equipment-service-select span');
			var tabClass = lobSpan.length ?
					lobSpan.data('lob-value').split("-") : $('.equipment-service-select').val().split("-");

			var lob = tabClass[0];

			var lobSize = this.parent.getLobEquipmentSize(lob);

			if (lobSize == 1 && !this.parent.getOutageForLob(lob)) {
				$('#account-products-tab').removeClass('active'); 
				$('#account-equipment-tab').addClass('active');
				this.parent.troubleshootLobOnlyDevice(lob);
			}
		},
		quicklinkClicked : function(e) {
			if (e) {
				//removes page reload in case there is a get parameter in the url
				e.preventDefault();
			}
			this.startTroubleshooting();
		},
		startTroubleshooting : function(lob) {
			var servicesTop = this.$el.offset().top;
			$('html,body').animate({ scrollTop:servicesTop});

			this.$troubleshootTab.tab('show');
			this.$el.addClass('troubleshooting');

			if (!lob) {
				lob = this.getDropdownLob();
			}

			this.troubleshootTabClicked(lob);
		},
		isAlreadyCached : function() {
			this.troubleshot = true;
		},
		troubleshootTabClicked : function(lob) {

			this.displayFooter('troubleshoot-tab');

			if (( lob && this.checkLobForSize( lob ) ) ) {
				return;
			}

			if (lob && typeof(lob) != "object") {
				this.changeLob(lob + "-tab");
			} else {
				this.setDefaultEquipmentTab();
			}

			//check all equipment
			if (!this.troubleshot) {
				this.troubleshot = true;
				
				this.$el.addClass('fetching-troubleshoot');

				this.parent.onCheckEquipment();
			} else {
				//change the troubleshoot button class so that it takes user to troubleshoot single device
				$(".device > button").removeClass("troubleshoot-all").addClass("troubleshoot-connection");

				this.checkForSingularDevice();
			}

			//add troubleshoot class to equipment tab pane
			this.$el.addClass('troubleshooting');
			
			this.displayFAQs('troubleshoot-tab');
		},

		equipmentTabClicked : function() {
			//hide the no equipment content, as if there's an equipment tab, there must be equipment
			this.$noEquipment.hide();
			this.$hasEquipment.show();

			//remove troubleshoot class from equipment tab pane
			this.$el.removeClass('troubleshooting');
			
			this.untroubleshootDevice();
			
			if (this.troubleshot) {
				$(".device > button").removeClass("troubleshoot-all").addClass("troubleshoot-connection");
			} else {
				$(".device > button").removeClass("troubleshoot-connection").addClass("troubleshoot-all");
			}

			this.$el.removeClass('troubleshoot-single-device');
			this.displayFAQs('equipment-tab');
			this.displayFooter('equipment-tab');
		},
		servicesTabClicked : function() {
			this.untroubleshootDevice();
			this.$el.removeClass('troubleshoot-single-device');
			this.displayFooter('services-tab');
		},
		lobChanged : function(e) {
			//show appropriate tab
			var tabClass = $(e.target).val();
			var change_lob = _.bind(this.changeLob, this);
			setTimeout(function() { change_lob(tabClass); }, 50);
		},
		changeLob : function(tabClass) {
			//show appropriate tab
			$(this.lobTabs + "." + tabClass).tab('show');
			$(this.lobSelect).val(tabClass);
			if (this.$el.hasClass('troubleshoot-single-device')) {
				this.$el.removeClass('troubleshoot-single-device');
				this.untroubleshootDevice();
				this.troubleshootTabClicked();
			} else if (this.$el.hasClass('troubleshooting')) {
				this.checkForSingularDevice();
			}
			
			var lob = this.getDropdownLob();
			var lobSize = this.parent.getLobEquipmentSize(lob);
			if (this.parent.getOutageForLob(lob) || (lobSize == 1 && this.$el.hasClass('troubleshooting'))) {
				$('.troubleshoot-connection').hide();
				$('.troubleshoot-all').hide();
			} else {
				$('.troubleshoot-connection').show();
				$('.troubleshoot-all').show();
			}

            $(this.lobSelect).blur();
			this.displayFAQs();
		},
		displayFAQs : function(activeServiceTab) {
			//Set activeServiceTab if non specified(when lobChanged)
			if( !activeServiceTab ){
				activeServiceTab = $('.service-tabs .active a').attr('id');
			}

			// Show FAQ's that should be on the Equipment tab and hide others
			if(activeServiceTab == 'equipment-tab') {
				$('.equipment-faq').show();
				$('.equipment-remotes').show();
				$('.troubleshooting-tips').hide();
				$('.equipment-bottom .account-tab-content >').removeClass('active');
				$('.equipment-bottom .equipment-bottom-tabs >').removeClass('active');
			// Show FAQ's that should be on the Troubleshoot tab and hide others
			} else {
				$('.equipment-faq').hide();
				$('.equipment-remotes').hide();
				$('.troubleshooting-tips').show();
				$('.equipment-bottom .account-tab-content >').removeClass('active');
				$('.equipment-bottom .equipment-bottom-tabs >').removeClass('active');
			}
		},
		displayFooter: function(activeServiceTab) {
			if (activeServiceTab == 'services-tab') {
				$('.shop-services').html('<span>Want to add or upgrade services?</span><a class="mys-btn" href="http://twc.com/shop">Shop Now</a>');
			}
			else if (activeServiceTab == 'equipment-tab') {
				$('.shop-services').html('<span>Want to add or upgrade equipment?</span><a class="mys-btn" href="http://twc.com/shop">Shop Now</a>');
				$(".equipment-bottom ul.text-list").show();
			}
			else {
				$('.shop-services').html('<span>If you need assistance, please</span> <a class="chat-link" data-chat-type="equipment:tv:troubleshoot" style="text-decoration:underline;">chat with an agent</a>.');
				$(".equipment-bottom ul.text-list").hide();
			}
		},
		hideOutage : function() {
			this.$servicesInstructions.show();
			this.$troubleshootInstructions.show();
			this.$outageAlert.hide();

			$('.troubleshoot-connection').show();
			$('.troubleshoot-all').show();
		},
		showOutage : function() {
			this.$outageAlert.show();
			this.$servicesInstructions.hide();
			this.$troubleshootInstructions.hide();

			$('.troubleshoot-connection').hide();
			$('.troubleshoot-all').hide();
		},
		showOutagePotential : function() {
			this.$potentialOutageAlert.show();
			this.$servicesInstructions.hide();
			this.$troubleshootInstructions.hide();
		},
		troubleshootDevice : function(device) {
			this.$troubleshootTab.parent().addClass('active');
			this.$equipmentTab.parent().removeClass('active');
			this.$servicesTab.parent().removeClass('active');

			this.$('.help-btn').hide();
            var lobID = $(this.lobSelect).is('select') ? $(this.lobSelect).val() : $(this.lobSelect+' span').data('lobValue');
            if(this.$("#equipment-"+ lobID + " .equipment-list li.device").length > 1){
				switch(lobID){
					case "tv-tab":
						$("#troubleshoot-change-equipment-tv").show();
						$("#troubleshoot-change-equipment-internet-homephone").hide();
					break;

					case "internet-tab":
						$("#troubleshoot-change-equipment-tv").hide();
						$("#troubleshoot-change-equipment-internet-homephone").show();
					break;

					case "homephone-tab":
						$("#troubleshoot-change-equipment-tv").hide();
						$("#troubleshoot-change-equipment-internet-homephone").show();
					break;
				}
			} else {
				$("#troubleshoot-change-equipment-tv").hide();
				$("#troubleshoot-change-equipment-internet-homephone").hide();
			}

			this.$el.addClass('troubleshooting troubleshoot-single-device');
			
			this.currentDevice = device;
			$(".automated-troubleshoot", this.currentDevice.$el).remove();
			this.currentDevice.$el.append(twc.utils.template(this.troubleshootContainerTemplate)({}));
			
			//determine which troubleshoot view to show
			if (this.currentDevice.model.get('isDumbDevice'))
				this.showTroubleshootNonProvisionable();
			else if (!this.currentDevice.model.canTroubleshoot())
				this.showTroubleshootUnavailable();
			else if (this.currentDevice.model.get('isCritical'))
				this.showTroubleshootCriticalStatus();
			else if (this.currentDevice.model.get('isLowMemory'))
				this.showTroubleshootLowMemory();
			else
				this.showTroubleshootSymptoms();
			
			//make sure to display correct elements for troubleshooting tab
			this.displayFAQs();
			this.displayFooter();

			this.trackTroubleshootingLink(this.currentDevice, "troubleshoot button", "troubleshoot button");
		},
		untroubleshootDevice : function() {
			$("#troubleshoot-change-equipment-tv").hide();
			$("#troubleshoot-change-equipment-internet-homephone").hide();
			this.$('.help-btn').show();
			this.parent.untroubleshootDevice();
			this.currentDevice = null;
		},
		showTroubleshootUnavailable: function() {
			var content = twc.utils.template(this.troubleshootUnavailableTemplate)({});
			this.updateTroubleshootView(content);
			
			var errorTmpl =  twc.utils.template('data-error');
			var error = errorTmpl({ message: twc.copy.get('requestHit/not-connected/error') });
			this.updateTroubleshootView(error, true);
			
			if (!twc.utils.MobileDetectionUtil.anyMobile()) {
				this.expandTroubleshootingTips();
			}
		},
		showTroubleshootManual: function(title) {
			var content = twc.utils.template(this.troubleshootManualTemplate)({title:title, isLowMemory:this.currentDevice.model.get('isLowMemory')});
			this.updateTroubleshootView(content);
			
			if (!twc.utils.MobileDetectionUtil.anyMobile()) {
				this.expandTroubleshootingTips();
			}
		},
		showTroubleshootNonProvisionable: function() {
			var errorTmpl =  twc.utils.template('data-error');
			var error = errorTmpl({ message: twc.copy.get('requestHit/not-connected/error') });
			this.updateTroubleshootView(error);
		},
		expandTroubleshootingTips: function() {
			var lob = this.currentDevice.model.get('lob');
			var tab = $('a[href="#' + lob + '-troubleshoot-tab"]');
			var paneActive = $('#' + lob + '-troubleshoot-tab').hasClass('active');
	        
			if (!paneActive) {
				setTimeout(function() { tab.trigger('click'); }, 50);
			}
		},
		expandTVTroubleshootingTips: function() {
			var tab = $('a[href="#tv-troubleshoot-tab"]');
			var paneActive = $('#tv-troubleshoot-tab').hasClass('active');
	        
			if (!paneActive)
	        	tab.trigger('click');
		},
		showTroubleshootSymptoms: function() {
			var symptomsContainer = $('.automated-troubleshoot', this.$el);
			if (symptomsContainer.length > 1) {
				var secondContainer = $(symptomsContainer[1]);
				secondContainer.remove();
			}
			
			var lob = this.getDropdownLob();
			var content = twc.utils.template(this.troubleshootSymptomTemplate)({lob:lob});
			this.updateTroubleshootView(content);
		
			this.trackTroubleshootingSubpageView(this.currentDevice, "symptoms", null, null);
		},
		showTroubleshootCriticalStatus: function() {
			var lob = this.currentDevice.model.get('lob');
			var content = twc.utils.template(this.troubleshootCriticalStatusTemplate)({lob:lob});
			this.updateTroubleshootView(content);

			this.trackTroubleshootingSubpageView(this.currentDevice, "symptom:critical status", "symptom:critical status", "critical status");
		},
		showTroubleshootLowMemory: function() {
			var lob = this.currentDevice.model.get('lob');
			var content = twc.utils.template(this.troubleshootLowMemoryTemplate)({});
			this.updateTroubleshootView(content);
			
			this.trackTroubleshootingSubpageView(this.currentDevice, "symptom:low memory", "symptom:low memory", "low memory");
		},
		showTroubleshootReboot: function(evt) {
			var lob = this.currentDevice.model.get('lob');
			var symptom = $(evt.currentTarget).text();
			var problemCode = $(evt.currentTarget).data('problem-code');
			var action = $(evt.currentTarget).data('ats-action');
			var content = "";
			
			if (problemCode && problemCode != "") {
				//Determine if automated troubleshooting is available for device. 
				//Show error message if unavailable. Otherwise show the reboot/reauthorize view.
				if (action == "Manual") {
					this.showTroubleshootManual(symptom);
				}
				else {
					var content = twc.utils.template(this.troubleshootRebootTemplate)({lob:lob, symptom:symptom, problemCode:problemCode, action:action});
					this.updateTroubleshootView(content);
				}
			}
			
			this.trackTroubleshootingSubpageView(this.currentDevice, "symptom:missing channel", "symptom:missing channel", symptom);
		},
		requestHit: function(evt) {
			var problemCode = $(evt.currentTarget).data('problem-code');
			var problemCodeName = this.lookupProblemCodeName(problemCode);
			var action = $(evt.currentTarget).data('ats-action');
			var symptom = $(".automated-troubleshoot h6 span.symptom").text();
			symptom = $.trim(symptom);
			
			var attempted = this.currentDevice.model.get('attemptedTroubleshoot');
			var attemptedJson = twc.utils.AjaxUtil.stringToJSON(attempted);
			var alreadyTroubleshooted = attemptedJson[symptom];

			if (action == "Manual") {
				this.showTroubleshootManual(symptom);
			}
			else if (!alreadyTroubleshooted) {
				var self = this;
				var serialNumber = this.currentDevice.model.get('serialNumber');

				$.ajax(twc.routes.get('account/equipment-request-hit'),{
		            type: 'POST',
		            contentType: "application/json",
		            data: '{ "serialNumber":"' + serialNumber + '", "problemCodeName":"' + problemCodeName + '" }'
		        }).done(function(resp){
	                if (resp && !resp.error){
	                	self.showTroubleshootInProgess(problemCode, action);
	                	self.saveTroubleshootAttempt(symptom);
	                }
	                else {
	                	self.showTroubleshootHitError();
	                }
	            }).fail(function(resp){
	            	self.showTroubleshootHitError();
	            });
			}
			else {
				//If user has already attempted to do an automatic troubleshoot for the current device 
				//and selected symptom (problemCode), show an error message
				this.showTroubleshootAttemptedError(symptom, action);
			}
		},
		lookupProblemCodeName: function(problemCode) {
			switch (problemCode) {
				case 'BP': return 'BoxProblem';
				case 'PI': return 'Picture';
				case 'BR': return 'BoxReset';
				case 'CG': return 'ChannelGuide';
				case 'LM': return 'LowMemory';
				case 'AC': return 'Activate';
				case 'PC': return 'PleaseCallMessage';
				case 'SD': return 'RecentSoftDisconnect';
				case 'MC': return 'MissingChannels';
				case 'IN': return 'ActivateInternet';
				case 'PH': return 'ActivatePhone';
				case 'IN': return 'ActivateInternet';
				case 'IR': return 'Internet_ModemRecentReconnect';
				case 'IO': return 'Internet_OnlineCantConnect';
			}
			return "";
		},
		showTroubleshootInProgess: function(problemCode, action) {
			var content = '';

			if (this.currentDevice.model.get('isLowMemory')) {
				content = twc.utils.template(this.troubleshootLowMemoryInProgressTemplate)({action:action});
			}
			else {
				var lob = this.currentDevice.model.get('lob');
				var symptom = $(".automated-troubleshoot h6 span.symptom").text();
				content = twc.utils.template(this.troubleshootInProgressTemplate)({lob:lob, symptom:symptom, action:action});
			}

			this.updateTroubleshootView(content);
			
			this.trackTroubleshootingSubpageView(this.currentDevice, action+" confirmation", action+" confirmation", symptom);
		},
		showTroubleshootHitError: function() {
			var symptom = $(".automated-troubleshoot h6 span.symptom").text();
			var content = twc.utils.template(this.troubleshootErrorTemplate)({symptom:symptom, isLowMemory:this.currentDevice.model.get('isLowMemory')});
			this.updateTroubleshootView(content);
			
			var errorTmpl =  twc.utils.template('data-error');
			var error = errorTmpl({ message: twc.copy.get('requestHit/error') });
			this.updateTroubleshootView(error, true);
		},
		showTroubleshootAttemptedError: function(symptom, action) {
			var lob = this.currentDevice.model.get('lob');
			var content = twc.utils.template(this.troubleshootAttemptedTemplate)({lob:lob, symptom:symptom, action:action});
			this.updateTroubleshootView(content);
			
			this.trackTroubleshootingSubpageView(this.currentDevice, "already attempted message", "already attempted message", symptom);
		},
		updateTroubleshootView: function(content, append) {
			if (this.currentDevice) {
				//update or append the automated troubleshoot module with new content
				if (append) 
					$(".automated-troubleshoot", this.currentDevice.$el).append(content);
				else
					$(".automated-troubleshoot", this.currentDevice.$el).html(content);
			} else {
				$(".automated-troubleshoot").html(content);
			}
		},
		saveTroubleshootAttempt: function(symptom) {
			//Save troubleshoot attempted status to cookie for current device
			var attempted = this.currentDevice.model.get('attemptedTroubleshoot');
			var attemptedJson = twc.utils.AjaxUtil.stringToJSON(attempted);
			attemptedJson[symptom] = true;
			attempted = twc.utils.AjaxUtil.jsonToString(attemptedJson);
			this.currentDevice.model.set('attemptedTroubleshoot', attempted);
			this.currentDevice.model.saveCookie();
		},
		trackTroubleshootingSubpageView: function(device, subpage, action, symptom) {
			var subpageName = 'ats:troubleshoot:';
	
			if (device) {
				var lob = device.model.get('lob');
				subpageName += lob + ':' + subpage;
			}
			else {
				subpageName += subpage;
			}
			
			var props = {
				events: 'event92',
				e63: subpageName,
				p63: subpageName,
				p3: ':div',
				e6: ':div',
				contextData: this.getTroubleshootTrackingContextData(device, action, symptom)
			};

			twc.omniture.addReportSuite('tsg2resecareprod');
			twc.omniture.track('event', 'sub page view:'+subpageName, props);
			twc.omniture.resetReportSuites();
		},
		trackTroubleshootingLink: function(device, link, action) {
			var linkName='ats:troubleshoot:' + this.getDropdownLob() + ':' + link;
			
			var symptom = null;
			if ( $(".automated-troubleshoot h6 span.symptom") ) 
				symptom = $(".automated-troubleshoot h6 span.symptom").text();
			
			var props = {
				events: 'event48',
				e7: linkName,
				p3: ':div',
				e6: ':div',
				contextData: this.getTroubleshootTrackingContextData(device, action, symptom)
			};
			
			twc.omniture.addReportSuite('tsg2resecareprod');
			twc.omniture.track('event', linkName, props);
			twc.omniture.resetReportSuites();
		},
		trackTroubleshootChat: function() {
			var pageName='ats:troubleshoot:' + this.getDropdownLob() + ":chat with agent";
			
			var symptom = null;
			if ( $(".automated-troubleshoot h6 span.symptom") ) 
				symptom = $(".automated-troubleshoot h6 span.symptom").text();
			
			var props = {
				events: 'event77',
				e67: pageName,
				e68: 'services > my services > my account',
				contextData: this.getTroubleshootTrackingContextData(this.currentDevice, "chat", symptom)
			};
			
			twc.omniture.addReportSuite('tsg2resecareprod');
			twc.omniture.track('event', pageName, props);
			twc.omniture.resetReportSuites();
		},
		trackTroubleshootContactUs: function() {
			this.trackTroubleshootingLink(this.currentDevice, "contact us", "contact us");
		},
		trackTroubleshootTips: function() {
			var lob = this.getDropdownLob();
			var tab = $('a[href="#' + lob + '-troubleshoot-tab"]');
			var expanded = $('#' + lob + '-troubleshoot-tab').hasClass('active');
	        
			if (!expanded)
				this.trackTroubleshootingLink(this.currentDevice, "troubleshooting tips", "troubleshoot tip");
		},
		getTroubleshootTrackingContextData: function(device, action, symptom){
			var contextData = {};
			contextData['ats_lob'] = this.getDropdownLob();
			
			if (device) {
				contextData['ats_status_type'] = device.model.get('status');
			}
				
			if (action) {
				contextData['ats_action'] = action;
			}
			
			if (symptom) {
				contextData['ats_symptom'] = $.trim(symptom);
			}
			
			return contextData;
		},
		getDropdownLob: function() {
			var lobTab;
			
			// The markup is different for single vs multiple lobs (span vs select)
			if ($('.equipment-service-select option').length) {
				lobTab = $('.equipment-service-select').val();
			} else if ($('.equipment-service-select span').length) {
				lobTab = $('.equipment-service-select span').data('lob-value');
            }
			
			if (lobTab)
				return lobTab.substr(0,lobTab.length-4);
			
			return "tv";
		}
	});

	//Main view for module
	this.Equipment = Backbone.View.extend({
		troubleshoot: null,
		outageFeatureEnabled: false,
		events: {
			'click #check-all-equipment' : 'onCheckEquipment'
		},

		initialize: function( options ) {
			var self = this;

			if (!!this.$el.data('troubleshoot')) {
				var troubleshootEl = this.$el.closest('.current-services');
				var start = window.location.hash.indexOf("troubleshoot") !== -1;
				this.troubleshoot = new views.Troubleshoot({el: troubleshootEl[0], parent:self, autoStart: options.autoStart});
			}

			if (!!this.$el.data('outage-enabled')) {
			    this.outageFeatureEnabled = true;
			}

			var isLogout;
			
			this.devices = new collections.Devices();
			this.deviceViews = [];

			this.help = this.$('.help-btn');
			this.deviceEls = this.$('.device');
			this.checkEquipment = this.$('#check-all-equipment');
			this.outageAlert = this.$('.service-outage');
			this.lobTabs = this.$('.lob-tabs');
			this.equipmentList = this.$('.equipment-list > li');

			this.devices.on('change:loading', this.onLoadingChange, this);
			this.devices.on('add', this.onDeviceAdded, this);
			this.devices.on('complete', function(model){
				if (self.troubleshoot) 
					self.troubleshoot.completedFetch();
			
				var views = self.deviceViews;

				if (model)
					views = [ _.find(views, function(v){ return v.model == model; }) ];

				// collect tracking values for all devices
				var statuses = _.map(views, function(v){
					return v.getTrackingValues();
				});

				trackStatus(statuses, self.$el);
			});

			this.devices.on('change:isOutageOccurring', this.checkOutageStatus, this);
			this.devices.on('complete', this.checkOutagePotential, this );
			this.devices.on('complete', this.updateDeviceOutage, this );

			this.addDevices();
			this.checkOutageStatus();

			this.devices.on('complete', function() {
				self.checkEquipment.attr('disabled', false);
			})

			this.setHelpPopover();
			$(window).on('unload', function() {
				if( isLogout ) return;
				self.devices.clearCounts();
			})

			$(window).on('logout', function() {
				isLogout = true;
				self.devices.clearCookies();
			});

			if (this.troubleshoot && this.devices.length && this.devices.hasCookies()) {	
				this.troubleshoot.isAlreadyCached();
			}
			if (options.autoStart && this.troubleshoot) {
				this.troubleshoot.startTroubleshooting();
			}
			
			if (twc.utils.MobileDetectionUtil.anyMobile()) {
				$('.equipment-bottom-tabs .troubleshooting-tips a').click(_.bind(this.showModalTroubleshootingTips, this));
				$('.troubleshoot-tips-modal .modal-header .mys-btn').click(_.bind(this.hideModalTroubleshootingTips, this));
			}
		},
		getOutageForLob : function(lob) {
			return this.outageFeatureEnabled && this.devices.isOutageOccurringForLob(lob);
		},
		checkOutageStatus: function() {
			if( this.devices.isOutageOccurring() && this.outageFeatureEnabled ) {
				this.showOutage();
			}
			else {
				this.hideOutage();
			}
		},
		checkOutagePotential: function() {
			if( this.devices.isPotentialOutage() ) {
				this.showOutagePotential();
			}
		},

		addDevices: function() {
			var items = $('.device', this.$el);
			var devices = this.devices;
			var lobs = {};

			items.each(function( index, element ){
				var el = $(element);
				var lob = el.data('lob');
				lobs[lob] = true;
				devices.add({ macAddress: el.data('mac-attr'),
							  serialNumber: el.data('serial'),
                              type: el.data('type'),
                              make: el.data('make'),
							  lob: lob });
			});

			devices.lobs = _.keys(lobs);
		},

		onDeviceAdded: function( device ) {
			var el = this.deviceEls[ this.devices.length - 1 ];

			this.deviceViews.push(new views.DeviceDisplay({ 
				el: el, 
				model: device, 
				troubleshoot: this.troubleshoot,
				parent: this
			}));
		},
		updateDeviceOutage : function() {
			_.each(this.deviceViews, function(view) {
				view.updateStatus(view.model, view.model.get('status'), view.model.get('status'));
			});
		},
		onCheckEquipment: function( event ) {
			var nonSignature = '';
			var signature = '';

			if( this.devices.hasProvisionalDevices() && !this.devices.fetch() ) {
				twc.errors.view.render(twc.copy.get('account/max-attempts-title'), twc.copy.get('account/max-attempts-body'));
			} else {
				this.checkEquipment.attr('disabled', true);
			}
		},
		onLoadingChange: function( model, value ) {
			this.checkEquipment.attr('disabled', value);
		},
		showOutage: function() {
			if (this.troubleshoot) {
				this.troubleshoot.showOutage();
			} else {
				this.outageAlert.show();
				this.lobTabs.addClass('outage-tabs');
			} 
		},
		hideOutage : function() {
			if (this.troubleshoot) {
				this.troubleshoot.hideOutage();
			} else {
				this.outageAlert.hide();
				this.lobTabs.removeClass('outage-tabs');
			}
		},
		showOutagePotential : function() {
			if (this.troubleshoot) {
				this.troubleshoot.showOutagePotential();
			} else {
				twc.errors.view.render(twc.copy.get('account/potential-outage-title'), twc.copy.get('account/potential-outage-body') );
			}
		},
		getEquipmentSize: function () {
			return $(".device").length;
		}, 
		getLobEquipmentSize : function (lob) {
			return $(".device", "#equipment-" + lob + "-tab").length;
		},
		hideAllDevices: function() {
			$(".device").hide();
		},
		showAllDevices: function() {
			$(".device").show();
		},
		hideAllTroubleshootDisplays: function() {
			$(".device .automated-troubleshoot").remove();
		},
		troubleshootLobOnlyDevice: function(lob) {
			if (this.getLobEquipmentSize(lob) !== 1) {
				return;
			};

			var self = this;
			_.each(this.deviceViews, function(view) {
				var containerIdArr = view.$el.closest('div.tab-pane').attr('id').split('-');
				if (view.model.get('lob') == lob && containerIdArr[1] == lob) {
					self.troubleshootDevice(view);
					return;
				}
			});
		},
		troubleshootDevice : function(device) {
			this.hideAllDevices();
			device.showDevice();
			this.troubleshoot.troubleshootDevice(device);
			$('.troubleshoot-connection').hide();
			$('.troubleshoot-all').hide();
		},
		untroubleshootDevice : function() {
			this.hideAllTroubleshootDisplays();
			this.showAllDevices();

			var lob = this.troubleshoot.getDropdownLob();

			if (this.outageFeatureEnabled && this.devices.isOutageOccurringForLob(lob)) {
				$('.troubleshoot-connection').hide();
				$('.troubleshoot-all').hide();
			} else {
				$('.troubleshoot-connection').show();
				$('.troubleshoot-all').show();
			}
		},
		setHelpPopover : function() {

			var direction = _.bind(this.getPopoverDirection, this);
			this.help.popover({
				html: true,
				trigger: 'hover',
				template: '<div class="equipment-help popover"><div class="arrow"></div><div class="popover-content"><p></p></div></div>',
				placement: direction
			});
			var shownCallback = _.bind(this.showHorizontalPopover, this);
			if (direction() == "bottom") {
				shownCallback = _.bind(this.showVerticalPopover, this);
			}
			this.help.on('shown', shownCallback);
			$('.popover-close').on('click', _.bind(this.closePopover, this));
			
			/*this.help.on('mouseover', function() {
				var pop, arrow;

				$(this).popover('show');

				pop = $('.equipment-help' );
				arrow = $('.arrow', pop );

				if( pop.length ) pop.css({ marginTop: pop.height() / 2 - arrow.position().top });
			});

			this.help.on('mouseout', function() {
				var pop, arrow;

				$(this).popover('hide');

				pop = $('.equipment-help' );
				arrow = $('.arrow', pop );

				if( pop.length ) pop.css({ marginTop: pop.height() / 2 - arrow.position().top });
			}); */


		},

		closePopover : function() {
			this.help.popover('hide');
		},
		showVerticalPopover : function() {
			var pop, arrow, top, left, offset, style;
			pop = $('.equipment-help');

			if( $(window).width() >= 420 ) {
				this.showHorizontalPopover();
				return;
			}

			arrow = $('.arrow', pop );
			if( pop.length ) {
				top = pop.position().top;
				left = pop.position().left;
				offset = pop.height() / 2 - arrow.position().top;

				style = { top: top };
				style.left = $(window).width() - pop.width() - 25;
				pop.css(style);
			}
		},
		showHorizontalPopover : function() {
			var pop, arrow, top, left, offset, style;
			pop = $('.equipment-help' );

			if( $(window).width() < 420 ) {
				this.showVerticalPopover();
				return;
			}

			arrow = $('.arrow', pop );
			if( pop.length ) {
				top = pop.position().top;
				left = pop.position().left;
				offset = pop.height() / 2 - arrow.position().top;

				style = { top: top + offset };
				if( $(window).width() >= 768 ) {
					style.left = left - arrow.position().left;
				}
				pop.css(style);
			}
		},
		getPopoverDirection : function() {
			var minRight = 768;
			var minLeft = 420;
			var w = $(window).width();

			var dir = w >= minRight ? "right" : "left"
			dir = w >= minLeft ? dir : "bottom";

			return dir;
		},
		showModalTroubleshootingTips: function(evt) {
			//show the modal view
			var troubleshootModal = $(evt.currentTarget).closest('.equipment-bottom').find('.troubleshoot-tips-modal');
			$(troubleshootModal).show();
            $('html').addClass('no-background-scrolling');
		},
		hideModalTroubleshootingTips: function(evt) {
			//trigger a troubleshooting tip button click to close the non-modal troubleshooting tips
			var troubleshootTipsButton = $(evt.currentTarget).closest('.tab-pane').find('.equipment-bottom .equipment-bottom-tabs .troubleshooting-tips a');
			$(troubleshootTipsButton).trigger('click');
			
	        //hide the modal view
	        var troubleshootModal = $(evt.currentTarget).closest('.troubleshoot-tips-modal');
			$(troubleshootModal).hide();
            $('html').removeClass('no-background-scrolling');
		},
		expandTroubleshootingTips : function() {
			var lobHref = $('li.active a', this.lobTabs).attr('href').split('-');
			var lob = lobHref[1];
			var tab = $('a[href="#' + lob + '-troubleshoot-tab"]');
			var paneActive = $('#' + lob + '-troubleshoot-tab').hasClass('active');
	     
			$("html,body").animate({ scrollTop: tab.position().top + $(window).height()}, 50);

			if (!paneActive) 
	        	tab.trigger('click');
		}
	});
});




